import { App } from 'vue';
import { createI18n, I18n, I18nOptions } from 'vue-i18n';

export type LocaleType = 'zh_CN' | 'en' | 'ru' | 'ja' | 'ko';

export const localList: any[] = [
	{
		type: 'zh_CN',
		name: '中文简体',
	},
	{
		type: 'en',
		name: 'English',
	},
];

export let i18n: any;

// 语言资源池
export const loadLocalePool: LocaleType[] = [];

// 设置html标签语言属性
export function setHtmlPageLang(locale: LocaleType) {
	document.querySelector('html')?.setAttribute('lang', locale);
}

// 调整资源池
export function setLoadLocalePool(cb: (loadLocalePool: LocaleType[]) => void) {
	cb(loadLocalePool);
}

// 获取当前语言环境
export function getCurrentLanguage() {
	let currentLanguage: LocaleType = localStorage.getItem(
		'language'
	) as LocaleType;
	if (!currentLanguage) {
		const language = navigator.language;
		currentLanguage = language.indexOf('zh') !== -1 ? 'zh_CN' : 'en';
	}
	return {
		locale: currentLanguage,
	};
}

// 设置当前语言环境
export function setCurrentLanguage(locale: LocaleType) {
	if (i18n.mode === 'legacy') {
		i18n.global.locale = locale;
	} else {
		(i18n.global.locale as any).value = locale;
	}
	setHtmlPageLang(locale);
	localStorage.setItem('language', locale);
}

// 国际化hooks
export function useLocale() {
	const { locale } = getCurrentLanguage();
	const getAntdLocale = computed((): any => {
		return i18n.global.getLocaleMessage(locale)?.antdLocale ?? {};
	});
	async function changeLocale(locale: LocaleType) {
		const globalI18n = i18n.global;
		const currentLocale = unref(globalI18n.locale);
		if (currentLocale === locale) {
			return locale;
		}
		if (loadLocalePool.includes(locale)) {
			setCurrentLanguage(locale);
			return locale;
		}
		const langModule = ((await import(`./lang/${locale}.ts`)) as any).default;
		if (!langModule) return;

		globalI18n.setLocaleMessage(locale, langModule);
		loadLocalePool.push(locale);
		setCurrentLanguage(locale);
		return locale;
	}

	return {
		changeLocale,
		getAntdLocale,
	};
}

// 动态加载语言资源
async function createI18nOptions(): Promise<I18nOptions> {
	const { locale } = getCurrentLanguage();
	const defaultLocal = await import(`./lang/${locale}.ts`);
	const message = defaultLocal.default ?? {};
	setHtmlPageLang(locale);
	setLoadLocalePool((loadLocalePool) => {
		loadLocalePool.push(locale);
	});
	return {
		legacy: false,
		globalInjection: true,
		locale: locale,
		messages: {
			[locale]: message,
		},
	};
}

// 装载i18n
export async function setupI18N(app: App<Element>) {
	const options = await createI18nOptions();
	i18n = createI18n(options) as I18n;
	app.use(i18n);
}
